package com.gitee.feizns.convert.method.valueof;

import com.gitee.feizns.convert.Converter;
import com.gitee.feizns.convert.method.AbstractMethodConverter;
import com.gitee.feizns.convert.method.MethodSelectionStrategy;
import com.gitee.feizns.convert.method.MethodWrapper;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @author feizns
 * @since 2019/5/29
 */
public abstract class AbstractMethodSelectionStrategyByConverter implements MethodSelectionStrategy {

    private AbstractMethodConverter abstractMethodConverter;

    public AbstractMethodSelectionStrategyByConverter(AbstractMethodConverter abstractMethodConverter) {
        this.abstractMethodConverter = abstractMethodConverter;
    }

    @Override
    public MethodWrapper find(Class<?> targetType, Object original, Method... methods) {
        for (Method method : methods) {
            Class<?> parameterType = getType(method);
            List<Converter> converters = abstractMethodConverter.getSupportConverter(parameterType);
            if (  converters.isEmpty() == false ) {
                return () -> {
                    for (Converter converter : converters) {
                        Object ret = converter.to(original, parameterType);
                        if ( ret != null ) {
                            return invoke(method, targetType, ret);
                        }
                    }
                    return null;
                };
            }
        }
        return null;
    }

    /**
     * 寻找具体的类型
     * @param method
     * @return
     */
    protected abstract Class<?> getType(Method method);

    /**
     * 方法调用的具体策略
     * @param method
     * @param targetType
     * @return
     */
    protected abstract Object invoke(Method method, Class<?> targetType, Object original);

}
